using Newtonsoft.Json;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Text;
using UnityEngine;

public class MsgBase
{
    /// <summary>
    /// 协议名
    /// </summary>
    public string ProtoName = "";

    /// <summary>
    /// 编码
    /// </summary>
    /// <param name="msgBase">消息</param>
    /// <returns></returns>
    public static byte[] Encode(MsgBase msgBase)
    {
        string s = JsonUtility.ToJson(msgBase);

        return Encoding.UTF8.GetBytes(s);
    }

    /// <summary>
    /// 解码
    /// </summary>
    /// <param name="protoName">协议名字</param>
    /// <param name="bytes">字节数组</param>
    /// <param name="offset">数据起始位置</param>
    /// <param name="count">长度</param>
    /// <returns></returns>
    public static MsgBase Decode(string protoName, byte[] bytes, int offset, int count)
    {

        string json = Encoding.UTF8.GetString(bytes, offset, count);
        Type type = Type.GetType(protoName);

        // 检查类型是否成功获取
        if (type == null)
        {
            Debug.LogError($"无法找到类型: {protoName}");
        }
        // 检查类型是否继承自 MsgBase
        if (!typeof(MsgBase).IsAssignableFrom(type))
        {
            Debug.LogError($"{protoName} 没有继承 MsgBase");
        }

        // 反序列化
        return (MsgBase)JsonUtility.FromJson(json, type);
    }

    /// <summary>
    /// 协议名编码
    /// </summary>
    /// <param name="msgBase"></param>
    /// <returns></returns>
    public static byte[] EncodeName(MsgBase msgBase)
    {
        byte[] nameBytes = Encoding.UTF8.GetBytes(msgBase.ProtoName);

        short len = (short)nameBytes.Length;

        byte[] bytes = new byte[len + 2];

        bytes[0] = (byte)(len & 0x00ff);
        bytes[1] = (byte)(len >> 8);

        Array.Copy(nameBytes, 0, bytes, 2, len);

        return bytes;
    }

    /// <summary>
    /// 协议名 解码
    /// </summary>
    /// <param name="bytes">字节数组</param>
    /// <param name="offset">起始位置</param>
    /// <param name="count">返回的解析长度</param>
    /// <returns></returns>
    public static string DecodeName(byte[] bytes, int offset, out int count)
    {
        count = 0;
        if (offset + 2 > bytes.Length)
        {
            return "";
        }

        short len = (short)(bytes[offset + 1] << 8 | bytes[offset]);

        if (len <= 0)
        {
            return "";
        }

        count = len + 2;

        return Encoding.UTF8.GetString(bytes, offset + 2, len);
    }
}
